package com.sr.examination.user.base;

import android.content.Context;
import android.text.TextUtils;

import com.alibaba.sdk.android.oss.ClientConfiguration;
import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.OSSClient;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
import com.alibaba.sdk.android.oss.callback.OSSProgressCallback;
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSStsTokenCredentialProvider;
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask;
import com.alibaba.sdk.android.oss.model.DeleteObjectRequest;
import com.alibaba.sdk.android.oss.model.DeleteObjectResult;
import com.alibaba.sdk.android.oss.model.ObjectMetadata;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.sr.examination.net.Net;
import com.sr.examination.user.Account;
import com.tl.commonlibrary.network.ErrorResponse;
import com.tl.commonlibrary.network.RequestListener;
import com.tl.commonlibrary.network.bean.base.BaseBean;
import com.tl.commonlibrary.tool.Logger;
import com.tl.commonlibrary.ui.BaseFragmentActivity;
import com.tl.commonlibrary.ui.beans.PicUploadInfoBean;

import retrofit2.Call;

/**
 * 文件上传
 */
public class FileUploadModel {

    public static final int FILE_TYPE_HEAD = 1; //用户头像
    public static final int FILE_TYPE_VIEDO = 2; //动态视频
    public static final int FILE_TYPE_VIEDO_COVER = 3; //动态视频封面
    public static final int FILE_TYPE_PICTURE = 4; //动态图文
    public static final int FILE_TYPE_LIVE_COVER = 5; //直播封面
    public static final int FILE_TYPE_LIVE_TRAILER = 6; //直播预告封面
    public static final int FILE_TYPE_IDCARD = 7; //身份认证照片

    private static final String TAG = "httputil";

    private IFileUploadedListener mListener;
    private BaseFragmentActivity mContext;
    private String mLocalFilePath;
    private int mFileType;
    private String mServerFilePath;
    private String mEndpoint;
    private String mDnsEndpoint;
    private OSSClient mOSSClient;
    private OSSAsyncTask mCurrentTask;
    private PicUploadInfoBean mAliStsBean;

    public FileUploadModel(BaseFragmentActivity context, IFileUploadedListener listener) {
        mContext = context;
        mListener = listener;
    }

    public void startUpload(String path, int mFileType) {
        this.mLocalFilePath = path;
        this.mFileType = mFileType;
        getUploadUrl();
    }

    private void getUploadUrl() {
        mContext.showProgressDialog();
        Net.getUploadUrl(new RequestListener<BaseBean<PicUploadInfoBean>>() {
            @Override
            public void onSuccess(Call<BaseBean<PicUploadInfoBean>> call, BaseBean<PicUploadInfoBean> response) {
                ossUpload(response.data, mLocalFilePath);
            }

            @Override
            public void onFailed(Call<BaseBean<PicUploadInfoBean>> call, ErrorResponse errorResponse) {
                if (mListener != null) {
                    mListener.onFileUploadedFailure();
                }
                mContext.dismissProgressDialog();
            }
        });
    }

    public static String getStreamType(int fileType) {
        switch (fileType) {
            case FILE_TYPE_HEAD:
            case FILE_TYPE_VIEDO_COVER:
            case FILE_TYPE_PICTURE:
            case FILE_TYPE_LIVE_COVER:
            case FILE_TYPE_LIVE_TRAILER:
            case FILE_TYPE_IDCARD:
                return "image/jpeg";
            case FILE_TYPE_VIEDO:
                return "video/*";
        }
        return null;
    }

    public String getFileName(int fileType) {
        switch (fileType) {
            case FILE_TYPE_HEAD:
                if (mLocalFilePath != null && mLocalFilePath.length() >= 17) {
                    return "avatar_" + mLocalFilePath.substring(mLocalFilePath.length() - 17, mLocalFilePath.length());
                } else {
                    return "avatar_" + System.currentTimeMillis() + ".jpg";
                }
            case FILE_TYPE_VIEDO:
                return "video_" + System.currentTimeMillis() + ".mp4";
            case FILE_TYPE_VIEDO_COVER:
                return "cover_" + System.currentTimeMillis() + ".jpg";
            case FILE_TYPE_PICTURE:
                return "pic_" + System.currentTimeMillis() + ".jpg";
            case FILE_TYPE_LIVE_COVER:
                return "live_cover_" + System.currentTimeMillis() + ".jpg";
            case FILE_TYPE_LIVE_TRAILER:
                return "live_trailer_" + System.currentTimeMillis() + ".jpg";
            case FILE_TYPE_IDCARD:
                return "idcard_" + System.currentTimeMillis() + ".jpg";
        }
        return "unkown";
    }

    private String getFilePath() {
        return Account.getUser().getUid() + "/";
    }


    private void initOss(PicUploadInfoBean bean) {
        mAliStsBean = bean;
        OSSCredentialProvider credentialProvider = new OSSStsTokenCredentialProvider(
                bean.getAccessKeyId(), bean.getAccessKeySecret(), bean.getSecurityToken());
//        shuren-exam.oss-cn-beijing.aliyuncs.com
        mEndpoint = formatUrl("oss-cn-beijing.aliyuncs.com", null);
        mDnsEndpoint = bean.getUrlPri();
        mServerFilePath = getFilePath() + getFileName(mFileType);
        ClientConfiguration conf = new ClientConfiguration();
        conf.setConnectionTimeout(20 * 1000); // 连接超时，默认15秒
        conf.setSocketTimeout(20 * 1000); // socket超时，默认15秒
        conf.setMaxConcurrentRequest(8); // 最大并发请求数，默认5个
        conf.setMaxErrorRetry(2); // 失败后最大重试次数，默认2次
        mOSSClient = new OSSClient(mContext.getApplicationContext(), mEndpoint, credentialProvider, conf);
    }

    private String formatUrl(String url, String headHost) {
        if (!TextUtils.isEmpty(headHost)) {
            url = headHost + "." + url;
        }
        if (!url.startsWith("http")) {
            url = "http://" + url;
        }
        return url;
    }

    private void ossUpload(PicUploadInfoBean bean, String uploadFilePath) {
        initOss(bean);
        // 指定数据类型，没有指定会自动根据后缀名判断
        ObjectMetadata objectMeta = new ObjectMetadata();
        objectMeta.setContentType(getStreamType(mFileType));
        // 构造上传请求
        PutObjectRequest put = new PutObjectRequest(bean.getBucket(), mServerFilePath, uploadFilePath);
        put.setMetadata(objectMeta);
        // 异步上传时可以设置进度回调
        put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
            @Override
            public void onProgress(PutObjectRequest putObjectRequest, long l, long l1) {
                Logger.d(TAG, "progress " + (l * 100) / l1);
                // 在这里可以实现进度条展现功能
                if (mListener != null) {
                    mListener.onFileUploadProgress(l, l1);
                }
                mContext.dismissProgressDialog();
            }
        });

        mCurrentTask = mOSSClient.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
            @Override
            public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                if (mListener != null) {
                    String url = mDnsEndpoint + "/" + mServerFilePath;
                    Logger.d(TAG, "UploadSuccess " + url);
                    mListener.onFileUploadedSuccess(url);
                    mContext.dismissProgressDialog();
                }
            }

            @Override
            public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                if (mListener != null) {
                    mListener.onFileUploadedFailure();
                }
                // 请求异常
                if (clientExcepion != null) {
                    // 本地异常如网络异常等
                    clientExcepion.printStackTrace();
                }
                if (serviceException != null) {
                    // 服务异常
                    Logger.e(TAG, serviceException.getErrorCode());
                    Logger.e(TAG, serviceException.getRequestId());
                    Logger.e(TAG, serviceException.getHostId());
                    Logger.e(TAG, serviceException.getRawMessage());
                }


                mContext.dismissProgressDialog();
                return;
            }
        });
    }

    public void destroy() {
        mListener = null;
        mOSSClient = null;
        if (mCurrentTask != null && !mCurrentTask.isCompleted()) {
            mCurrentTask.cancel();
        }
        mCurrentTask = null;
    }

    public void deleteObject(String url) {
        if (TextUtils.isEmpty(url)) {
            return;
        }
        int index = url.lastIndexOf("/");
        String fileName = url.substring(index + 1);
        Logger.d(TAG, "delete " + getFilePath() + fileName);
        // 创建删除请求
        DeleteObjectRequest delete = new DeleteObjectRequest(mAliStsBean.getBucket(),
                getFilePath() + fileName);
        // 异步删除
        mCurrentTask = mOSSClient.asyncDeleteObject(delete, new OSSCompletedCallback<DeleteObjectRequest, DeleteObjectResult>() {
            @Override
            public void onSuccess(DeleteObjectRequest request, DeleteObjectResult result) {
                Logger.d(TAG, "delete success!");
            }

            @Override
            public void onFailure(DeleteObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                // 请求异常
                if (clientExcepion != null) {
                    // 本地异常如网络异常等
                    clientExcepion.printStackTrace();
                }
                if (serviceException != null) {
                    // 服务异常
                    Logger.e(TAG, "ErrorCode" + serviceException.getErrorCode());
                    Logger.e(TAG, "RequestId" + serviceException.getRequestId());
                    Logger.e(TAG, "HostId" + serviceException.getHostId());
                    Logger.e(TAG, "RawMessage" + serviceException.getRawMessage());
                }
            }

        });
    }

    public interface IFileUploadedListener {
        public void onFileUploadProgress(long currentSize, long totalSize);

        public void onFileUploadedSuccess(String url);

        public void onFileUploadedFailure();
    }
}
